home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2001 May / may_2001.iso / intercd / root / Multimedia / ^DivX_Article / virtualdub / VirtualDub-source-1_4d / a_mjpgdec.asm < prev    next >
Encoding:
Assembly Source File  |  2001-03-20  |  7.5 KB  |  490 lines

  1. ;    VirtualDub - Video processing and capture application
  2. ;    Copyright (C) 1998-2001 Avery Lee
  3. ;
  4. ;    This program is free software; you can redistribute it and/or modify
  5. ;    it under the terms of the GNU General Public License as published by
  6. ;    the Free Software Foundation; either version 2 of the License, or
  7. ;    (at your option) any later version.
  8. ;
  9. ;    This program is distributed in the hope that it will be useful,
  10. ;    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ;    GNU General Public License for more details.
  13. ;
  14. ;    You should have received a copy of the GNU General Public License
  15. ;    along with this program; if not, write to the Free Software
  16. ;    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18.     .586
  19.     .mmx
  20.     .model    flat
  21.     
  22. DCTLEN_PROFILE = 0
  23.  
  24.  
  25.     IF    DCTLEN_PROFILE
  26.  
  27.     extern _short_coeffs: dword
  28.     extern _med_coeffs: dword
  29.     extern _long_coeffs: dword
  30.  
  31.     ENDIF
  32.  
  33.     .code
  34. __start:
  35.  
  36.  
  37. ;    EBP    bit bucket
  38. ;    ESI    bit source
  39. ;    CL    24 - bits in bucket
  40.  
  41. FILLBITS    macro
  42.     local    noneed, notmarker, loop
  43.  
  44.     cmp    dl,-8
  45.     jl    noneed
  46. loop:
  47.     movzx    eax,byte ptr [esi]
  48.     mov    ecx,000000101h
  49.     add    ecx,eax
  50.     shr    ecx,8
  51.     add    esi,ecx
  52.  
  53.     mov    cl,dl
  54.     add    cl,8
  55.     shl    eax,cl
  56.     or    ebp,eax
  57.     sub    dl,8
  58.     jns    loop
  59. noneed:
  60.     endm
  61.  
  62. NEEDBITS    macro at        ;EAX, EDX, EBX available
  63.     local    done,short_ok,ick
  64.  
  65.     cmp    dl,16-at
  66.     jle    done
  67.  
  68.     movzx    eax,word ptr [esi]
  69.     bswap    eax
  70.     shr    eax,16
  71.  
  72.     mov    ecx,eax
  73.     lea    ebx,[eax+01010101h]
  74.     and    ecx,80808080h
  75.     not    ebx
  76.     and    ebx,ecx
  77.     jz    short_ok
  78. ick:
  79.     call    sucks2
  80. short_ok:
  81.     mov    cl,dl
  82.     shl    eax,cl
  83.     sub    dl,16
  84.     or    ebp,eax
  85.     add    esi,2
  86. done:
  87.     endm
  88.  
  89. NEEDBITS2    macro at        ;EAX, EDX available
  90.     local    done,short_ok,ick
  91.  
  92. ;    cmp    dl,16-at
  93. ;    jle    done
  94.     or    dl,dl
  95.     js    done
  96.  
  97.     movzx    eax,word ptr [esi]
  98.     bswap    eax
  99.     shr    eax,16
  100.  
  101.     lea    ecx,[eax+01010101h]
  102.     not    ecx
  103.     and    ecx,eax
  104.     test    ecx,80808080h
  105.     jz    short_ok
  106. ick:
  107.     call    sucks2
  108. short_ok:
  109.     mov    cl,dl
  110.     shl    eax,cl
  111.     sub    dl,16
  112.     or    ebp,eax
  113.     add    esi,2
  114. done:
  115.     endm
  116.  
  117. ALIGN16    macro
  118.     local    x
  119. x = ((__start - $) and 15)
  120.     rept    x
  121.     nop
  122.     endm
  123.     endm
  124.  
  125. ; decode_mbs(dword& bitbuf, int& bitcnt, byte *& ptr, int mcu_length, MJPEGBlockDef *pmbd, int **dctptrarray);
  126.  
  127. l_size        = 32
  128. l_mb        = 0
  129. l_huffac    = 4
  130. l_dctptr    = 8
  131. l_quantptr    = 12
  132. l_quantlimit    = 16
  133. l_acquick    = 20
  134. l_acquick2    = 24
  135. l_bitcnt    = 28
  136. l_save        = 29
  137.  
  138. p_bitbuf    = l_size + 4 + 16
  139. p_bitcnt    = l_size + 8 + 16
  140. p_ptr        = l_size + 12 + 16
  141. p_mb_count    = l_size + 16 + 16
  142. p_blocks    = l_size + 20 + 16
  143. p_dctptrarray    = l_size + 24 + 16
  144.  
  145. block        struct
  146. huff_dc        dd    ?
  147. huff_ac        dd    ?
  148. huff_ac_quick    dd    ?
  149. huff_ac_quick2    dd    ?
  150. quant        dd    ?
  151. dc_ptr        dd    ?
  152. ac_last        dd    ?
  153. block        ends
  154.  
  155.     public _asm_mb_decode
  156.  
  157. _asm_mb_decode:
  158.     push    ebp
  159.     push    edi
  160.     push    esi
  161.     push    ebx
  162.  
  163.     sub    esp,l_size
  164.  
  165.     mov    dword ptr [esp + l_mb],0
  166.     mov    ebp, [esp + p_bitbuf]
  167.     mov    ecx, [esp + p_bitcnt]
  168.     mov    esi, [esp + p_ptr]
  169.     mov    ebp,[ebp]
  170.     mov    edx,[ecx]
  171.     mov    esi,[esi]
  172.     sub    dl,8
  173.  
  174. mb_loop:
  175.     mov    eax,[esp + p_blocks]
  176.  
  177.     mov    ebx,[eax].block.quant
  178.     add    ebx,8
  179.     mov    [esp + l_quantptr],ebx
  180.     mov    ecx,[eax].block.huff_ac_quick
  181.     mov    [esp + l_acquick],ecx
  182.     mov    ecx,[eax].block.huff_ac_quick2
  183.     mov    [esp + l_acquick2],ecx
  184.     mov    ebx,[eax].block.huff_ac
  185.     mov    [esp + l_huffac],ebx
  186.  
  187.     push    eax
  188.     mov    ebx,[esp + p_dctptrarray + 4]
  189.     mov    eax,[ebx]
  190.     mov    [esp + l_dctptr + 4],eax
  191.     add    ebx,4
  192.     mov    [esp + p_dctptrarray+ 4],ebx
  193.  
  194.     mov    eax,[esp+l_quantptr+4]
  195.     add    eax,63*8
  196.     mov    [esp + l_quantlimit+4], eax
  197.  
  198.     pop    eax
  199.  
  200.     FILLBITS
  201.  
  202.     ;decode DC coefficient
  203.  
  204.     mov    [esp + l_bitcnt],dl
  205.  
  206.     mov    ecx,ebp
  207.     shr    ecx,30
  208.     shl    ebp,2
  209.     xor    eax,eax
  210.     xor    ebx,ebx
  211.     mov    edi,[esp + p_blocks]
  212.     mov    edi,[edi].block.huff_dc
  213.  
  214. DC_decode_loop:
  215.     movzx    edx,byte ptr [edi + eax + 1]
  216.     sub    ecx,edx
  217.     jc    DC_decode_loop_term
  218.     add    ebp,ebp
  219.     adc    ecx,ecx
  220.     add    ebx,edx
  221.     inc    eax
  222.     jmp    short DC_decode_loop
  223.  
  224. DC_decode_loop_term:
  225.     add    ecx,edx
  226.     mov    dl,[esp + l_bitcnt]
  227.     add    dl,al
  228.     add    dl,2
  229.     
  230.     add    ebx,ecx
  231.     jz    no_DC_difference
  232.  
  233.     mov    eax,ebx
  234.  
  235.     ;sign-extend DC difference
  236.  
  237.     cmp    ebp,80000000h
  238.     sbb    ebx,ebx
  239.     mov    cl,al
  240.  
  241.     mov    eax,ebx
  242.     shld    eax,ebp,cl
  243.     shl    ebp,cl
  244.     sub    eax,ebx
  245.     add    dl,cl
  246.  
  247.     ;DC difference is now in EAX
  248.  
  249. no_DC_difference:
  250.     mov    ebx,[esp + p_blocks]
  251.     mov    ebx,[ebx].block.dc_ptr
  252.     mov    edi,[esp + l_quantptr]
  253.     imul    eax,[edi-8]
  254.     add    eax,[ebx]
  255.     mov    [ebx],eax
  256.     mov    ecx,[esp + l_dctptr]
  257.     mov    [ecx+0],al
  258.     mov    [ecx+1],ah
  259.  
  260.     ;***** BEGIN DECODING AC COEFFICIENTS
  261.  
  262.     mov    ebx,[esp+l_quantptr]
  263.     jmp    short AC_loop
  264.  
  265.  
  266.     ;AC coefficient loop
  267.     ;
  268.     ;    EBX    quantization pointer
  269.     ;    DL    bitcnt
  270.     ;    ESI    bitptr
  271.     ;    EBP    bitheap
  272.  
  273.     ALIGN16
  274. AC_loop:
  275.     or    dl,dl
  276.     jns    AC_reload
  277.  
  278. AC_reload_done:    
  279.     cmp    ebp,0ff800000h
  280.     jae    AC_long_decode
  281.     cmp    ebp,0b0000000h
  282.     jae    AC_medium_decode
  283.  
  284.     ;table-based decode for short AC coefficients
  285.  
  286.     IF    DCTLEN_PROFILE
  287.     inc    dword ptr [_short_coeffs]
  288.     ENDIF
  289.  
  290.     mov    eax,ebp
  291.     mov    edi,[esp + l_acquick]
  292.     shr    eax,25
  293.     mov    cl,[edi + eax*2 + 1]
  294.     movsx    eax,byte ptr [edi + eax*2]
  295.  
  296.     shl    ebp,cl
  297.     add    dl,cl
  298.     or    eax,eax
  299.     jz    AC_exit
  300.  
  301. AC_decode_coefficient:
  302.  
  303.     ;multiply coefficient by quant. matrix entry and store
  304.  
  305.     mov    edi,[esp + l_dctptr]
  306.     mov    ecx,[ebx+4]
  307.     imul    eax,[ebx]
  308.     mov    [edi + ecx],ax
  309.     add    ebx,8
  310.  
  311.     ;end of AC coefficient loop
  312.  
  313.     cmp    ecx,63*2
  314.     jne    AC_loop
  315.     jmp    AC_exit
  316.  
  317.     ALIGN16
  318. AC_reload:
  319.     movzx    eax,word ptr [esi]
  320.     bswap    eax
  321.     shr    eax,16
  322.  
  323.     mov    ecx,eax
  324.     lea    edi,[eax+01010101h]
  325.     and    ecx,80808080h
  326.     not    edi
  327.     and    edi,ecx
  328.     jz    short_ok
  329. ick:
  330.     call    sucks2
  331. short_ok:
  332.     mov    cl,dl
  333.     shl    eax,cl
  334.     sub    dl,16
  335.     or    ebp,eax
  336.     add    esi,2
  337. done:
  338.     jmp    AC_reload_done
  339.  
  340.     ALIGN16
  341. AC_medium_decode:
  342.     IF    DCTLEN_PROFILE
  343.     inc    dword ptr [_med_coeffs]
  344.     ENDIF
  345.  
  346.     mov    eax,ebp
  347.     mov    edi,[esp + l_acquick2]
  348.     shr    eax,20
  349.     mov    cl,[edi+eax*2 + 1 - 1600h]
  350.     lea    edi,[edi+eax*2]
  351.  
  352.     shl    ebp,cl
  353.     add    dl,cl
  354.  
  355.     ; parse out actual code
  356.  
  357.     NEEDBITS2 16
  358.  
  359.     movzx    ecx,byte ptr [edi - 1600h]
  360.  
  361.     cmp    cl,0f0h
  362.     jz    AC_skip16
  363.  
  364. AC_do_long:
  365.     mov    eax,ecx
  366.     and    ecx,15            ;ebx = size bits
  367.  
  368.     shr    eax,4            ;eax = skip
  369.  
  370.     lea    ebx,[ebx+eax*8]
  371.  
  372.     cmp    ebp,80000000h
  373.     sbb    eax,eax
  374.  
  375.     mov    edi,eax
  376.     shld    eax,ebp,cl
  377.     shl    ebp,cl
  378.     sub    eax,edi
  379.     add    dl,cl
  380.  
  381.     mov    edi,[esp + l_dctptr]
  382.     mov    ecx,[ebx+4]
  383.     imul    eax,[ebx]
  384.     mov    [edi + ecx],ax
  385.     add    ebx,8
  386.  
  387.     ;end of AC coefficient loop
  388.  
  389.     cmp    ecx,63*2
  390.     jne    AC_loop
  391.     jmp    AC_exit
  392.  
  393.     ALIGN16
  394. AC_exit:
  395.     mov    ebx,dword ptr [ebx-4]
  396.     shr    ebx,1
  397.  
  398.     ;all done with this macroblock!
  399.  
  400.     mov    eax,[esp + p_blocks]
  401.     mov    [eax].block.ac_last,ebx
  402.     add    eax,sizeof block
  403.     mov    [esp + p_blocks],eax
  404.  
  405.     mov    eax,[esp + l_mb]
  406.     inc    eax
  407.     cmp    eax,[esp + p_mb_count]
  408.     mov    [esp + l_mb],eax
  409.     jb    mb_loop
  410.  
  411.     ;finish
  412. fastexit:
  413.     mov    eax,[esp + p_bitbuf]
  414.     mov    ebx,[esp + p_bitcnt]
  415.     mov    ecx,[esp + p_ptr]
  416.     add    dl,8
  417.  
  418.     movsx    edx,dl
  419.  
  420.     mov    [eax], ebp
  421.     mov    [ebx], edx
  422.     mov    [ecx], esi
  423.  
  424.     add    esp,l_size
  425.     pop    ebx
  426.     pop    esi
  427.     pop    edi
  428.     pop    ebp
  429.  
  430.     ret
  431.  
  432.  
  433.  
  434.  
  435.  
  436.     ;start long AC decode
  437.     ;
  438.     ;    16: 00-7F
  439.     ;    15: 00-3F
  440.     ;    14: 00-1F
  441.  
  442.     ALIGN16
  443. AC_long_decode:
  444.     IF    DCTLEN_PROFILE
  445.     inc    dword ptr [_long_coeffs]
  446.     ENDIF
  447.     mov    eax,ebp
  448.     mov    [esp+l_quantptr],ebx
  449.     shr    eax,32-16
  450.     mov    ebx,[esp + l_huffac]
  451.     movzx    edi,byte ptr [ebx+eax*2-0FF80h*2]
  452.     mov    cl,byte ptr [ebx+eax*2-0FF80h*2+1]
  453.     shl    ebp,cl
  454.     add    dl,cl
  455.  
  456.     NEEDBITS    16
  457.  
  458.     mov    ecx,edi
  459.     mov    ebx,[esp + l_quantptr]
  460.  
  461.     jmp    AC_do_long
  462.  
  463.     ALIGN16
  464. sucks2:
  465.     movzx    eax,byte ptr [esi]
  466.     lea    ecx,[eax+1]
  467.     shr    ecx,8
  468.     add    esi,ecx
  469.  
  470.     shl    eax,8
  471.     movzx    ecx,byte ptr [esi+1]
  472.  
  473.     add    eax,ecx
  474.     inc    ecx
  475.     shr    ecx,8
  476.     add    esi,ecx
  477.  
  478.     ret
  479.  
  480.     ;reset 16 coefficients to zero
  481.  
  482.     ALIGN16
  483. AC_skip16:
  484.     add    ebx,16*8
  485.     cmp    ebx,[esp + l_quantlimit]
  486.     jae    AC_exit
  487.     jmp    AC_loop
  488.  
  489.     end
  490.